package main

import (
	"3d-space/internal/api"
	"3d-space/internal/database"
	"3d-space/internal/middleware"
	"bytes"
	"embed"
	"io"
	"io/fs"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"github.com/joho/godotenv"
)

//go:embed web/*
var embeddedWebFS embed.FS

func main() {
	gin.SetMode(gin.ReleaseMode)

	// 加载环境变量
	if err := godotenv.Load(); err != nil {
		log.Println("警告: 未找到 .env 文件，将使用系统环境变量")
	}

	// 验证必需的环境变量
	if os.Getenv("TENCENT_SECRET_ID") == "" || os.Getenv("TENCENT_SECRET_KEY") == "" {
		log.Println("警告: 未配置腾讯云密钥，AI 生成功能将不可用")
	}

	// 初始化数据库
	if err := database.Init("./data.db"); err != nil {
		log.Fatal("数据库初始化失败:", err)
	}
	defer database.Close()

	// 创建 Gin 路由
	r := gin.Default()

	// Session 中间件
	store := cookie.NewStore([]byte("your-secret-key-change-in-production"))
	r.Use(sessions.Sessions("session", store))

	// API 路由分组
	public := r.Group("/api")
	{
		public.POST("/register", api.Register)
		public.POST("/login", api.Login)
		public.GET("/space/:username", api.GetPublicSpace)
		public.GET("/model/:id/file", api.GetModelFile)
	}

	auth := r.Group("/api")
	auth.Use(middleware.AuthRequired())
	{
		auth.POST("/logout", api.Logout)
		auth.GET("/profile", api.GetProfile)
		auth.PUT("/space/toggle", api.ToggleSpace)

		auth.POST("/models/generate", api.GenerateModel)
		auth.POST("/models/upload", api.UploadModel)
		auth.GET("/models", api.ListMyModels)
		auth.PUT("/models/:id", api.UpdateModel)
		auth.DELETE("/models/:id", api.DeleteModel)

		auth.POST("/models/:id/comments", api.AddComment)
	}

	// 前端静态资源处理（嵌入 Go 可执行文件）
	fsys, err := fs.Sub(embeddedWebFS, "web")
	if err != nil {
		log.Fatal("无法加载嵌入资源:", err)
	}

	r.NoRoute(func(c *gin.Context) {
		path := strings.TrimPrefix(c.Request.URL.Path, "/")
		if strings.HasPrefix(path, "api") {
			c.JSON(http.StatusNotFound, gin.H{"error": "API not found"})
			return
		}

		if path == "" {
			path = "index.html"
		}

		file, err := fsys.Open(path)
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "File not found"})
			return
		}
		defer file.Close()

		data, _ := io.ReadAll(file)
		info, _ := file.Stat()
		http.ServeContent(c.Writer, c.Request, path, info.ModTime(), bytes.NewReader(data))
	})

	log.Println("生产模式服务启动在 :8081")
	if err := r.Run(":8081"); err != nil {
		log.Fatal("启动失败:", err)
	}
}
